<template>
  <div class="userspace-data-container">
    <div class="userspace-data-filesOperator">
      <!-- 左边操作栏 -->
      <div class="left">
        <div class="unCheckedOperator" v-if="this.checkedFileIndex.length <= 0">
          <el-upload
            class="uploadButton"
            :action="ip + 'uploadUserData/' + userInfo.id"
            name="multipartFile"
            :data="currentFilePath"
            :show-file-list="false"
            :on-success="onSuccess"
            :on-error="onError"
            :on-progress="onProgress"
            :before-upload="beforeUpload"
          >
            <el-button type="primary" size="small" class="upload">
              <i class="fa-solid fa-cloud-arrow-up"></i> 上传</el-button
            >
          </el-upload>
          <el-button size="small" class="common-btn" @click="newFolder">
            <i class="fa-solid fa-plus"></i>新建文件夹</el-button
          >
          <el-button size="small" class="common-btn" @click="checkAll">
            <i class="fa-solid fa-square-check"></i>
            全选</el-button
          >
          <el-button size="small" class="common-btn" @click="folderBack">
            <i class="fa-solid fa-arrow-rotate-left"></i>
            返回</el-button
          >
        </div>

        <div class="checkedOperator" v-else>
          <el-button size="small" class="common-btn" @click="checkAll">
            <i class="fa-solid fa-square-check"></i>
            全选</el-button
          >
          <el-button size="small" class="common-btn" @click="renameFile">
            <i class="fa-solid fa-spell-check"></i>
            重命名
          </el-button>
          <el-button size="small" class="common-btn" @click="downFile">
            <i class="fa-solid fa-cloud-arrow-down"></i>
            下载
          </el-button>
          <el-button size="small" class="common-btn" @click="deleteFile">
            <i class="fa-solid fa-trash-can"></i>
            删除
          </el-button>
        </div>
      </div>
      <!-- 右边操作栏 -->
      <div class="right">
        <div class="search">
          <el-input
            placeholder="请输入内容"
            v-model="searchContent"
            :clearable="true"
            @keyup.native.enter="searchFile(searchContent)"
            @clear="searchFileBac"
          >
          </el-input>
          <i
            class="fa-solid fa-magnifying-glass search-i"
            @click="searchFile(searchContent)"
          ></i>
        </div>
        <div class="sortType">
          <el-popover
            width="120"
            trigger="hover"
            :visible-arrow="false"
            popper-class="sortPopover"
          >
            <div
              :class="sortType == 1 ? 'sortTypeItemChecked' : 'sortTypeItem'"
              @click="sortFile(1)"
            >
              <i class="fa-solid fa-check"></i>
              按文件名称排序
            </div>
            <div
              :class="sortType == 2 ? 'sortTypeItemChecked' : 'sortTypeItem'"
              @click="sortFile(2)"
            >
              <i class="fa-solid fa-check"></i>
              按修改时间排序
            </div>
            <div
              :class="sortType == 3 ? 'sortTypeItemChecked' : 'sortTypeItem'"
              @click="sortFile(3)"
            >
              <i class="fa-solid fa-check"></i>
              按文件大小排序
            </div>
            <i slot="reference" class="fa-solid fa-arrow-down-short-wide"></i>
          </el-popover>
        </div>
        <div class="displayType" @click="fileDisplay">
          <i class="fa-solid fa-list" v-show="displayType == 1"></i>
          <i class="el-icon-menu" v-show="displayType == 2"></i>
        </div>
      </div>
    </div>
    <div class="usersapce-data-filesContent">
      <!-- 图标展示 -->
      <div class="fileDisplay-icon" v-if="displayType == 1">
        <div class="fileItem newfolder" v-show="showNewfolderTemplate">
          <i class="fa-solid fa-square-check"></i>
          <div class="imgContainer">
            <img src="filesImg/folder.png" alt="" />
          </div>
          <input
            id="newFolderName"
            type="text"
            class="renameInput"
            v-model="newFolderName"
            @change="folderRename('new')"
          />
        </div>
        <div
          v-for="(file, index) in filesTree"
          @dblclick="openFolder(file)"
          @click="fileChecked(index)"
          :class="
            checkedFileIndex.includes(index) ? 'fileItem-checked' : 'fileItem'
          "
          :key="index"
        >
          <i class="fa-solid fa-square-check"></i>
          <div class="imgContainer">
            <img :src="'filesImg/' + file.fileType + '.png'" alt="" />
          </div>
          <input
            type="text"
            class="renameInput"
            v-model="file.fileName"
            :id="'input' + index"
            @change="folderRename('old')"
            @blur="inputBlur"
            :disabled="
              checkedFileIndex.includes(index) && renameFilebtnClickTag
                ? false
                : true
            "
          />
        </div>
      </div>
      <!-- 列表展示 -->
      <div class="fileDisplay-list" v-if="displayType == 2">
        <div class="fileList-title">
          <div class="title"><span>文件名</span></div>
          <div class="time">修改时间</div>
          <div class="size">文件大小</div>
        </div>
        <!-- 新建文件夹 -->
        <div class="fileList-item newfolder" v-show="showNewfolderTemplate">
          <div class="title">
            <div class="imgContainer">
              <img src="filesImg/folder.png" alt="" />
            </div>
            <input
              id="newFolderName"
              type="text"
              class="renameInput"
              v-model="newFolderName"
              @change="folderRename('new')"
            />
          </div>
          <div class="time">
            <span>-</span>
          </div>
          <div class="size">
            <span>-</span>
          </div>
        </div>
        <!-- 列表循环 -->
        <div
          v-for="(file, index) in filesTree"
          :key="index"
          @dblclick="openFolder(file)"
          @click="fileChecked(index)"
          :class="
            checkedFileIndex.includes(index)
              ? 'fileList-item-checked'
              : 'fileList-item'
          "
        >
          <div class="title">
            <i class="fa-solid fa-square-check"></i>
            <div class="imgContainer">
              <img :src="'filesImg/' + file.fileType + '.png'" alt="" />
            </div>
            <input
              type="text"
              class="renameInput"
              v-model="file.fileName"
              :id="'input' + index"
              @change="folderRename('old')"
              @blur="inputBlur"
              :disabled="
                checkedFileIndex.includes(index) && renameFilebtnClickTag
                  ? false
                  : true
              "
            />
          </div>
          <div class="time">
            <span>{{ dateFormate(file.updateTime) }}</span>
          </div>
          <div class="size">
            <span>{{ sizeFormat(file.fileSize) }}</span>
          </div>
        </div>
      </div>
    </div>
    <!-- 文件上传进度展示 -->
    <div id="progressContainer" class="progressContainer">
      <div class="title">
        <span>{{ uploadFile.name }}</span>
      </div>
      <div class="progressItem">
        <!-- 上传进度条 -->
        上传进度:
        <el-progress
          :percentage="uploadFile.progress"
          color="#696bcc"
          class="uploadProgress"
        ></el-progress>
      </div>
      <div class="tips">tips: 上传过程中,请不要离开该页面哦!</div>
    </div>
  </div>
</template>
<script>
import { config } from "../../plugins/config.js";
import "../../assets/css/userspacedata.css";
import axios from "axios";
export default {
  data() {
    return {
      ip: config.ip,
      userInfo: JSON.parse(localStorage.getItem("user")),
      timeOut: null, //控制双击不触发单击事件
      checkedFileIndex: [], //选中文件的索引
      currentFilePath: {
        dataPath: "",
      }, //当前路径
      filesTree: [
        {
          absolutePath: "",
          childrenFileList: null,
          fileName: "测试文件夹",
          filePath: "\\7085456f-19a4-4f60-98ef-08f43d860620\\测试文件夹",
          fileSize: null,
          fileType: "folder",
          updateTime: null,
        },
        {
          absolutePath: "",
          childrenFileList: [],
          fileName: "测试图片.png",
          filePath: "\\7085456f-19a4-4f60-98ef-08f43d860620\\测试图片.png",
          fileSize: 919054,
          fileType: "image",
          updateTime: "2022-11-22T06:35:19.371+00:00",
        },
      ], //目录树
      filesTreeBac: [],
      uploadFile: {
        name: "testFile",
        progress: 0,
      }, //上传文件信息
      searchFiled: [], //搜索的文件
      showNewfolderTemplate: false, //显示新建文件夹卡片
      newFolderName: "", //新文件夹名字
      renameFilebtnClickTag: false, //重命名按钮点击标记
      sortType: 1, //1 按名称排序，2 按修改时间排序，3 按大小排序
      sortOrder: 1, //1 从小打到，-1从大到小
      displayType: 1, //1 图标，2 详细列表
      // 文件搜索框输入内容
      searchContent: "",
    };
  },
  methods: {
    // 上传成功
    onSuccess(response, file) {
      console.log(response);

      if (response == "ok") {
        this.$message.success("文件上传成功!");
        this.getFilesTree(this.currentFilePath);

        // this.isUploadProgressShow = false;
      } else {
        this.$message.error("上传失败,请稍后重试!");
      }
    },

    // 上传失败
    onError(err, file) {
      this.$message.error("上传失败,请稍后重试!");
      console.log(err);
    },

    // 文件上传时
    onProgress(e, file) {
      this.uploadFile.progress = parseInt(e.percent); // 动态获取文件上传进度
      if ((this.uploadFile.progress = 100)) {
        this.loadProgress = 100;
        setTimeout(() => {
          this.showFileProgress(-340);
        }, 1000); // 一秒后关闭进度条
      }
    },

    // 文件上传之前
    beforeUpload(file) {
      this.showFileProgress(10);
      this.uploadFile.name = file.name;
    },
    // 打开文件夹
    openFolder(file) {
      clearTimeout(this.timeOut);
      if (file.fileType == "folder") {
        this.currentFilePath.dataPath = file.filePath;
        this.getFilesTree(this.currentFilePath);
      }
    },
    // 新建文件夹点击
    newFolder() {
      // 激活输入框
      this.showNewfolderTemplate = true;
      setTimeout(() => {
        var input = document.getElementById("newFolderName");
        input.disabled = false;
        input.focus();
      }, 66);
    },
    // 文件列表输入框失去焦点
    inputBlur() {
      this.renameFilebtnClickTag = false;
      var input = document.getElementById("input" + this.checkedFileIndex[0]);
      input.disabled = true;
      input.style.cursor = "pointer";
    },
    // 重命名文件和文件夹
    folderRename(type) {
      const _this = this;
      switch (type) {
        case "new":
          if (this.uniqueFolder(this.newFolderName)) {
            var newfile = {
              fileName: this.newFolderName,
              filePath:
                this.currentFilePath.dataPath + "\\" + this.newFolderName,
              updateTime: new Date(),
              fileType: "folder",
            };
            axios
              .post(this.ip + "newFolder/" + this.userInfo.id, newfile)
              .then((res) => {
                if (res.data == "ok") {
                  _this.filesTree.unshift(newfile);
                  _this.$message.success("文件夹创建成功！");
                }
              });
          } else {
            this.$message.error("此位置包含同名文件夹，新建文件夹失败！");
          }
          this.showNewfolderTemplate = false;
          this.newFolderName = "";
          break;
        case "old":
          axios
            .post(
              this.ip + "renameFile",
              this.filesTree[this.checkedFileIndex[0]]
            )
            .then((res) => {
              if (res.data == "ok") {
                this.inputBlur();
              }
            });
          break;
        default:
          break;
      }
    },
    // 删除选中文件（文件夹）
    deleteFile() {
      const _this = this;
      var files = new Array();
      for (let i = 0; i < this.checkedFileIndex.length; i++) {
        const elFileIndex = this.checkedFileIndex[i];
        files.push(this.filesTree[elFileIndex]);
      }
      axios.post(this.ip + "deleteFiles", files).then((res) => {
        if (res.data == "ok") {
          _this.checkedFileIndex.splice(0, _this.checkedFileIndex.length);
          _this.getFilesTree(_this.currentFilePath);
        }
      });
    },
    // 下载文件
    async downFile() {
      let url = this.ip + this.userInfo.id + "/";
      for (let i = 0; i < this.checkedFileIndex.length; i++) {
        var elFileIndex = this.checkedFileIndex[i];
        var fileName = this.filesTree[elFileIndex].fileName;
        url = url + fileName;
        await fetch(url, {
          headers: new Headers({
            Origin: location.origin,
          }),
          mode: "cors",
        })
          .then((response) => response.blob())
          .then((blob) => {
            let blobUrl = window.URL.createObjectURL(blob);
            const a = document.createElement("a");
            a.download = fileName;
            a.href = blobUrl;
            document.body.appendChild(a);
            a.click();
            a.remove();
          })
          .catch((e) => console.error(e));
      }
    },
    // 重命名文件或文件夹按钮点击事件
    renameFile() {
      if (this.checkedFileIndex.length != 1) {
        this.$message.error("重命名失败!请选择一个文件（文件夹）");
        return;
      }
      this.renameFilebtnClickTag = true;

      var input = document.getElementById("input" + this.checkedFileIndex[0]);
      input.disabled = false;
      input.focus();
      input.style.cursor = "text";
    },
    // 选中文件
    fileChecked(index) {
      // 1.鼠标选中样式控制
      if (this.renameFilebtnClickTag) {
        //禁止点击输入框取消选中
        return;
      }
      clearTimeout(this.timeOut);
      this.timeOut = setTimeout(() => {
        let arrayIndex = this.checkedFileIndex.indexOf(index);
        if (arrayIndex > -1) {
          this.checkedFileIndex.splice(arrayIndex, 1);
        } else {
          this.checkedFileIndex.push(index);
        }
      }, 200);
    },
    // 全选
    checkAll() {
      let fileCount = this.filesTree.length;
      let checkedFileCount = this.checkedFileIndex.length;
      this.checkedFileIndex.splice(0, checkedFileCount);
      if (fileCount == checkedFileCount) {
        return;
      }
      let fileIndex = 0;
      while (fileIndex < fileCount) {
        this.checkedFileIndex.push(fileIndex);
        fileIndex++;
      }
    },
    // 返回上一级
    folderBack() {
      var currentFoldPath = this.currentFilePath.dataPath;
      var n = currentFoldPath.lastIndexOf("\\");
      if (n <= 0) {
        return;
      }
      console.log("返回上一级");
      this.currentFilePath.dataPath = currentFoldPath.slice(0, n);
      this.getFilesTree(this.currentFilePath);
    },
    // 获取当前目录下的文件结构数
    getFilesTree(folderPath) {
      const _this = this;
      axios.post(this.ip + "getCurDirFiles", folderPath).then((resp) => {
        // console.log(resp.data);
        // console.log(resp.data);
        _this.filesTree = resp.data;
        _this.filesTreeBac = _this.filesTree;
      });
    },
    // 展示上传文件进度条
    showFileProgress(right) {
      let process = document.getElementById("progressContainer");
      process.style.right = right + "px";
    },
    // 文件选中样式更改
    currentClass(index) {
      checkedFileIndex == index ? "fileItem-checked" : "fileItem";
    },
    // 判断文件夹是否重命名
    uniqueFolder(name) {
      for (let i = 0; i < this.filesTree.length; i++) {
        const elFile = this.filesTree[i];
        if (elFile.fileType == "folder" && elFile.fileName == name) {
          return false;
        }
      }
      return true;
    },
    // 文件排序
    sortFile(sorttype) {
      if (this.sortType == sorttype) {
        this.sortOrder = -this.sortOrder;
      }
      this.sortType = sorttype;
      this.sortAlgo(sorttype, this.sortOrder);
    },
    // 文件排序算法
    sortAlgo(sorttype, sortOrder) {
      for (let i = 0; i < this.filesTree.length - 1; i++) {
        for (let j = 0; j < this.filesTree.length - 1 - i; j++) {
          if (this.filesTree[j].fileType == "folder") {
            continue;
          }
          switch (sorttype) {
            case 1:
              if (sortOrder == 1) {
                if (
                  this.filesTree[j].fileName > this.filesTree[j + 1].fileName
                ) {
                  const temp = this.filesTree[j];
                  this.filesTree.splice(j, 1, this.filesTree[j + 1]);
                  this.filesTree.splice(j + 1, 1, temp);
                }
              } else {
                if (
                  this.filesTree[j].fileName < this.filesTree[j + 1].fileName
                ) {
                  const temp = this.filesTree[j];
                  this.filesTree.splice(j, 1, this.filesTree[j + 1]);
                  this.filesTree.splice(j + 1, 1, temp);
                }
              }
              break;
            case 2:
              if (sortOrder == 1) {
                if (
                  this.filesTree[j].updateTime >
                  this.filesTree[j + 1].updateTime
                ) {
                  const temp = this.filesTree[j];
                  this.filesTree.splice(j, 1, this.filesTree[j + 1]);
                  this.filesTree.splice(j + 1, 1, temp);
                }
              } else {
                if (
                  this.filesTree[j].updateTime <
                  this.filesTree[j + 1].updateTime
                ) {
                  const temp = this.filesTree[j];
                  this.filesTree.splice(j, 1, this.filesTree[j + 1]);
                  this.filesTree.splice(j + 1, 1, temp);
                }
              }
              break;
            case 3:
              if (sortOrder == 1) {
                if (
                  this.filesTree[j].fileSize > this.filesTree[j + 1].fileSize
                ) {
                  const temp = this.filesTree[j];
                  this.filesTree.splice(j, 1, this.filesTree[j + 1]);
                  this.filesTree.splice(j + 1, 1, temp);
                }
              } else {
                if (
                  this.filesTree[j].fileSize < this.filesTree[j + 1].fileSize
                ) {
                  const temp = this.filesTree[j];
                  this.filesTree.splice(j, 1, this.filesTree[j + 1]);
                  this.filesTree.splice(j + 1, 1, temp);
                }
              }
              break;
            default:
              break;
          }
        }
      }
    },
    // 文件展示方案
    fileDisplay() {
      switch (this.displayType) {
        case 1:
          this.displayType = 2;

          break;
        case 2:
          this.displayType = 1;
          break;
        default:
          break;
      }
    },
    // 时间格式化
    dateFormate(dateIn) {
      if (dateIn == null || dateIn == "") {
        return "-";
      }
      let date = new Date(dateIn);
      let Mon = date.getMonth() + 1;
      let year = date.getFullYear();
      let day = date.getDate();
      let Hour = date.getHours();
      let mm = date.getMinutes();
      return year + "/" + Mon + "/" + day + " " + Hour + ":" + mm;
    },
    //文件大小格式化
    sizeFormat(oriSize) {
      if (oriSize == null || oriSize == "") {
        return "-";
      }
      return (oriSize / 1048576).toFixed(2) + " MB";
    },
    // 文件搜索
    searchFile(searchContent) {
      this.searchFiled = [];
      for (let i = 0; i < this.filesTreeBac.length; i++) {
        const fileName = this.filesTreeBac[i].fileName;
        if (fileName.search(searchContent) != -1) {
          this.searchFiled.push(this.filesTreeBac[i]);
        }
      }
      this.filesTree = this.searchFiled;
    },
    // 文件搜索回退
    searchFileBac() {
      console.log("文件回退");
      this.filesTree = this.filesTreeBac;
    },
  },
  mounted() {
    const _this = this;
    this.currentFilePath.dataPath = "\\" + this.userInfo.id;
    this.getFilesTree(this.currentFilePath);
  },
};
</script>
<style scoped>
.sortType {
  margin: 0px 10px;
  cursor: pointer;
}
.sortType i {
  font-size: 20px;
  color: rgba(66, 66, 66, 0.6);
}
.sortTypeItem {
  font-size: 14px;
  position: relative;
  padding: 5px 0px;
  padding-left: 5px;
  border-radius: 6px;
  cursor: pointer;
}
.sortTypeItem i {
  color: white;
}
.sortTypeItemChecked {
  font-size: 14px;
  position: relative;
  cursor: pointer;
  padding: 5px 0px;
  padding-left: 5px;
  border-radius: 6px;
  color: rgb(20, 121, 215);
  font-weight: 600;
}

.sortTypeItem:hover {
  background-color: #f1f3f8;
}
.sortTypeItemChecked:hover {
  background-color: #f1f3f8;
}
</style>